<template>
  <div class="date-tools" :style="`width: ${width}px`">
    <div class="date-years">
      <span>{{ panelYear }}年{{ panelMonth + 1 }}月</span>
      <div>
        <el-button size="mini" @click="lastMonth ">上个月</el-button>
        <el-button size="mini" @click="nextMonth">下个月</el-button>
      </div>
    </div>

    <!-- 星期 -->
    <div class="date-weeks">
      <span v-for="day in week" :key="day">{{ day }}</span>
    </div>

    <!-- 天  -->
    <div class="date-days">
      <template v-for="(day, index) in dayFullList">
        <div
          v-if="day.includes('day-')"
          :key="index"

          :class="{
            'disabled':setDisabledFun(day,panelYear,panelMonth)
          }"
          class="dayButton"
          @click="!setDisabledFun(day,panelYear,panelMonth)&&getClickDay(day)"
        >
          <slot :days="day" />
        </div>
        <div
          v-else
          :key="index"
          :class="{
            active:getActiveDay(day),
            disabled:setDisabledFun(day,panelYear,panelMonth) }"
          class="dayButton"
          @click="!setDisabledFun(day,panelYear,panelMonth)&&getClickDay(day)"
        >
          <slot :days="day" />
        </div>
      </template>
    </div>

    <!-- 直接到选择时间 -->
    <div class="date-time" style="display:flex;">
      <el-input v-model="panelDate" size="mini" placeholder="请输入内容" @change="panelDateChange" />
      <el-time-picker v-model="panelTime" size="mini" :format="format" :value-format="format" placeholder="任意时间点" />
    </div>
  </div>
</template>

<script>
import moment from "moment";

export default {
  props: {
    activeDay: {
      type: Array,
      default: () => []
    },
    activeTime: {
      type: String,
      default: () => "16:00:00"
    },
    startingweek: {
      type: [Number, String],
      default: () => 0
    },
    setDisabledFun: {
      type: Function,
      default: () => false
    },
    activeCurrentDay: {
      type: Boolean,
      default: () => true
    },
    width: {
      type: [Number, String],
      default: () => 300
    },
    // 搜索分显示格式
    format: {
      type: String,
      default: "HH:mm"
    }
  },

  data() {
    return {
      week: ["日", "一", "二", "三", "四", "五", "六"],

      dayFullList: [], // 所有的天数列表，前面空位补0
      panelYear: "", // 全局展示的年
      panelMonth: "", // 全局展示的月（从0开始）
      panelTime: this.activeTime.toString(),
      panelDate: this.activeDay.toString(),

      lastDay: "", // 每月最后一天也即每月多少天

      lastMonthDay: "", // 获取上个月多少天
      firstDayisWhat: "", // 第一天星期几0-6（星期日到星期六）

      lastDayisWhat: "" // 最后一天星期几0-6（星期日到星期六）
    };
  },
  watch: {
    panelTime: {
      handler(val) {
        this.$emit("update:activeTime", val);
      },
      deep: true,
      immediate: true

    }

  },
  mounted() {
    this.dateInit();
  },
  methods: {
    // 上月
    lastMonth() {
      let month;
      if (Number(this.panelMonth) <= 0) {
        month = 11;
        this.panelYear = parseInt(this.panelYear) - 1;
      } else {
        month = Number(this.panelMonth) - 1;
      }
      this.updateDays(this.panelYear, month);
    },
    // 下个月
    nextMonth() {
      let month;
      if (Number(this.panelMonth) >= 11) {
        month = 0;
        this.panelYear = parseInt(this.panelYear) + 1;
      } else {
        month = Number(this.panelMonth) + 1;
      }
      this.updateDays(this.panelYear, month);
    },
    // 直接跳转输入时间月份
    panelDateChange(val) {
      const flag = /^(\d{4})-(\d{2})-(\d{2})$/;
      // 验证是否是时间格式
      if (flag.test(val)) {
        // 初始化时间
        const y = moment(val).format("YYYY");
        const m = parseInt(moment(val).format("M")) - 1;
        this.dateInit(y, m);

        this.$emit("update:activeDay", [moment(val).format("YYYY-MM-DD")]);
        this.panelDate = moment(val).format("YYYY-MM-DD");
      } else {
        this.panelDate = this.activeDay.toString();
      }
    },

    dateInit(year = new Date().getFullYear(), month = new Date().getMonth()) {
      const y = year; // 获取传入的年  默认 new Date().getFullYear()
      const m = month; // 获取传入的月 默认 new Date().getMonth()
      this.panelYear = year; // 全局展示的年
      this.panelMonth = month; // 全局展示的月
      this.lastDay = new Date(y, m + 1, 0).getDate(); // 每月最后一天也即每月多少天

      this.lastMonthDay = new Date(y, m, 0).getDate(); // 获取上个月多少天
      this.firstDayisWhat = new Date(y, m, 1).getDay(); // 第一天星期几0-6（星期日到星期六）

      this.lastDayisWhat = new Date(y, m + 1, 0).getDay(); // 最后一天星期几0-6（星期日到星期六）

      const beginTmp = []; // 初始化头部填充 非当前月的数据都是day开头
      // 头部拿到 firstDayisWhat 当月第一天是周几 去循环 用lastMonthDay上个月的总天数

      if (
        ((7 - this.startingweek + this.firstDayisWhat) % 7) +
          ((6 - this.lastDayisWhat + this.startingweek) % 7) >=
          11 &&
        this.lastDay > 28
      ) {
        for (
          let i = 0;
          i < (7 - this.startingweek + this.firstDayisWhat) % 7;
          i++
        ) {
          beginTmp.push(
            `upday-${this.lastMonthDay -
              (((7 - this.startingweek + this.firstDayisWhat) % 7) - i - 1)}`
          );
        }
      } else {
        if (
          this.startingweek + this.firstDayisWhat === 7 ||
          (6 - this.lastDayisWhat + this.startingweek === 0 &&
            this.lastDay === 28)
        ) {
          for (
            let i = 0;
            i < ((7 - this.startingweek + this.firstDayisWhat) % 7) + 14;
            i++
          ) {
            beginTmp.push(
              `upday-${this.lastMonthDay -
                (((7 - this.startingweek + this.firstDayisWhat) % 7) +
                  14 -
                  i -
                  1)}`
            );
          }
        } else {
          for (
            let i = 0;
            i < ((7 - this.startingweek + this.firstDayisWhat) % 7) + 7;
            i++
          ) {
            beginTmp.push(
              `upday-${this.lastMonthDay -
                (((7 - this.startingweek + this.firstDayisWhat) % 7) +
                  7 -
                  i -
                  1)}`
            );
          }
        }
      }

      // 初始化完整的月的每天格式为年月日
      const lastFullTmp = [];
      // 拿到lastDay本月的天数循环拼接完整年月日 panelYear panelMonth i addPreZero方法补零
      for (let i = 1; i <= this.lastDay; i++) {
        lastFullTmp.push(
          `${this.panelYear}-${this.addPreZero(
            this.panelMonth + 1
          )}-${this.addPreZero(i)}`
        );
      }

      // 尾部填充
      const lastinTmp = [];
      // 获取最后一天是周几

      for (
        let i = 0;
        i < (6 - this.lastDayisWhat + this.startingweek) % 7;
        i++
      ) {
        lastinTmp.push(`downday-0${i + 1}`);
      }

      // 拼接数组拿到当前月完整的数据
      this.dayFullList = [...beginTmp, ...lastFullTmp, ...lastinTmp];
    },

    // 小于9的需要添加0前缀
    addPreZero(num) {
      return num > 9 ? num : "0" + num;
    },
    // 设置选中的日期
    getActiveDay(day) {
      if (this.activeCurrentDay && moment().format("YYYY-MM-DD").includes(day)) {
        return true;
      }
      return this.activeDay.includes(day);
    },

    filterDay(value) {
      return parseInt(value.slice(-2));
    },

    getClickDay(day) {
      if (day.includes("downday") || day.includes("upday")) {
        const days = day.split("-");
        let y = this.panelYear;
        let m;
        if (day.includes("downday")) {
          if (this.panelMonth === 11) {
            m = 1;
            y = this.panelYear + 1;
          } else {
            m = this.panelMonth + 2;
          }
        } else {
          if (this.panelMonth === 0) {
            m = 12;
            y = this.panelYear - 1;
          } else {
            m = this.panelMonth;
          }
        }

        m = m < 10 ? "0" + m : m;
        const dateVal = y + "-" + m + "-" + days[1];

        const y1 = new Date(dateVal).getFullYear(); // 获取传入的年  默认 new Date().getFullYear()
        const m1 = new Date(dateVal).getMonth();

        this.dateInit(y1, m1);
        this.$emit("getClickDay", dateVal);
        this.panelDate = dateVal;
      } else {
        this.panelDate = day;
        this.$emit("getClickDay", day);
      }
    },
    updateDays(year = this.panelYear, month = this.panelMonth) {
      this.dateInit(year, month);
      this.panelYear = year;
      this.panelMonth = month;
    }
  }
};
</script>
<style lang="scss" scoped>
.date-tools {
  min-width: 300px;
  .date-years {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 15px;
    font-size: 13px;
  }
  .date-weeks {
    display: flex;
    border-bottom: 1px solid #d7dce5;
    padding-bottom: 10px;
    span {
      width: calc(100% / 7);
      text-align: center;
      color: #929aac;
      font-size: 13px;
    }
  }
  .date-days {
    display: flex;
    flex-wrap: wrap;
    .dayButton {
      width: calc(100% / 7);
      min-height: 40px;
      background-color: #fff;
      display: flex;
      align-items: center;
      justify-content: center;
      &:hover {
        background-color: #f2f8fe;
        span:not(.othermonths) {
          color: #1989fa;
        }
      }
      span {
        width: 20px;
        height: 14px;
        line-height: 14px;
        border-radius: 50%;
        font-size: 12px;
        text-align: center;
        cursor: pointer;
      }
      .othermonths {
        color: #e3e3e3;
      }
      .currentmonth {
        color: #000;
      }
    }
    .active {
      background-color: #f2f8fe;
      cursor: pointer;
      span.currentmonth {
        background-color: #fff;
        color: #1989fa;
      }
    }
    .disabled {
      background-color: #f5f7fa;
      opacity: 1;
      cursor: not-allowed;
      color: #c0c4cc;
      &:hover {
        span:not(.othermonths) {
          color: #c0c4cc;
        }
      }
    }
  }
}
</style>
